home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH08 / GETI.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-06  |  2.7 KB  |  98 lines

  1. ; GETI.ASM
  2. ;
  3. ; This module contains the integer input routine for the matrix
  4. ; example in Chapter Eight
  5.  
  6.         .nolist
  7.         include    stdlib.a
  8.         .list
  9.  
  10.         include    matrix.a
  11.  
  12. InpSeg        segment    para public 'input'
  13.  
  14. ; Geti-    On entry, es:di points at a string of characters.
  15. ;    This routine skips any leading spaces and comma characters and then
  16. ;    tests the first (non-space/comma) character to see if it is a digit.
  17. ;    If not, this routine returns the carry flag set denoting an error.
  18. ;    If the first character is a digit, then this routine calls the
  19. ;    standard library routine "atoi2" to convert the value to an integer.
  20. ;    It then ensures that the number ends with a space, comma, or zero
  21. ;    byte.
  22. ;
  23. ;    Returns carry clear and value in AX if no error.
  24. ;    Returns carry set if an error occurs.
  25. ;
  26. ;    This routine leaves ES:DI pointing at the character it fails on when
  27. ;     converting the string to an integer.  If the conversion occurs without
  28. ;    an error, the ES:DI points at a space, comma, or zero terminating byte.
  29.  
  30.  
  31. geti        proc    far
  32.  
  33.         ifdef    debug
  34.         print
  35.         char    "Inside GETI",cr,lf,0
  36.         endif
  37.  
  38. ; First, skip over any leading spaces or commas.
  39. ; Note the use of the "byp" symbol to save having to type "byte ptr".
  40. ; BYP is a text equate appearing in the macros.a file.
  41. ; A "byte ptr" coercion operator is required here because MASM cannot
  42. ; determine the size of the memory operand (byte, word, dword, etc)
  43. ; from the operands.  I.e., "es:[di]" and ' ' could be any of these
  44. ; three sizes.
  45. ;
  46. ; Also note a cute little trick here; by decrementing di before entering
  47. ; the loop and then immediately incrementing di, we can increment di before
  48. ; testing the character in the body of the loop.  This makes the loop
  49. ; slightly more efficient and a lot more elegant.
  50.  
  51.         dec    di
  52. SkipSpcs:    inc    di
  53.         cmp    byp es:[di], ' '
  54.         je    SkipSpcs
  55.         cmp    byp es:[di], ','
  56.         je    SkipSpcs
  57.  
  58. ; See if the first non-space/comma character is a decimal digit:
  59.  
  60.         mov    al, es:[di]
  61.         cmp    al, '-'        ;Minus sign is also legal in integers.
  62.         jne    TryDigit
  63.         mov    al, es:[di+1]    ;Get next char, if "-"
  64.  
  65. TryDigit:    isdigit
  66.         jne    BadGeti        ;Jump if not a digit.
  67.  
  68. ; Okay, convert the characters that follow to an integer:
  69.  
  70. ConvertNum:    atoi2            ;Leaves integer in AX
  71.         jc    BadGeti        ;Bomb if illegal conversion.
  72.  
  73. ; Make sure this number ends with a reasonable character (space, comma,
  74. ; or a zero byte):
  75.  
  76.         cmp    byp es:[di], ' '
  77.         je    GoodGeti
  78.         cmp    byp es:[di], ','
  79.         je    GoodGeti
  80.         cmp    byp es:[di], 0
  81.         je    GoodGeti
  82.  
  83.         ifdef    debug
  84.         print
  85.         char    "GETI: Failed because number did not end with "
  86.         char    "a space, comma, or zero byte",cr,lf,0
  87.         endif
  88.  
  89. BadGeti:    stc            ;Return an error condition.
  90.         ret
  91.  
  92. GoodGeti:    clc            ;Return no error and an integer in AX
  93.         ret
  94. geti        endp
  95.  
  96.  
  97. InpSeg        ends
  98.         end